package com.xc.smart.service.impl;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xc.smart.entity.GoodsOrder;
import com.xc.smart.entity.User;
import com.xc.smart.entity.dto.GoodsDto;
import com.xc.smart.service.GoodsOrderService;
import com.xc.smart.utlis.R;
import org.springframework.stereotype.Service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xc.smart.mapper.GoodsMapper;
import com.xc.smart.entity.Goods;
import com.xc.smart.service.GoodsService;

import javax.annotation.Resource;

/**
 *   秒杀 指定商品秒杀-》生成订单（库存锁定）-》支付-》扣减/不支付回滚
 *   @author mtl
 *   2021/6/23
 */   
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements GoodsService{

    @Resource
    GoodsOrderService goodsOrderService;

    @Override
    public List<Goods> list() {
        List<Goods> list = baseMapper.selectList(new QueryWrapper<Goods>().eq(Goods.COL_IS_SALE, 1));
        return list;
    }

    @Override
    public R spike(User user, GoodsDto dto) {
        //用户判定 商品判定：数量 价格：：有效性
        if(user==null){
            return R.error("请登录");
        }
        //减余额 库存锁定
        //异步生成订单
        //订单支付 库存扣减 否则回滚库存
        return null;
    }

    @Override
    public R buy(User user, GoodsDto dto) {
        if(BeanUtil.isEmpty(dto)){
            return R.error("输入参数不足");
        }
        Goods goods = check_Inventory(dto.getId());
        if(Convert.toInt(goods.getGoodsStock()) <1||Convert.toInt(goods.getGoodsStock()) <dto.getNumber()){
            return R.error("库存不足");
        }
        reduce_Inventory(goods.getId(),dto.getNumber());
        GoodsOrder order = new GoodsOrder();
        order.setUserId(user.getId());
        order.setGoodsId(dto.getId());
        order.setOrderPrice(goods.getShopPrice());
        order.setOrderState(0);
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());
        goodsOrderService.save(order);
        return R.ok().put("data",order.getId()).put("goods",goods.getGoodsStock().subtract(new BigDecimal(dto.getNumber())));
    }

    @Override
    public Goods check_Inventory(Integer goodsId) {
        Goods goods = baseMapper.selectById(goodsId);
        return goods;
    }

    @Override
    public synchronized void reduce_Inventory(Integer goodsId, Integer number) {
        Goods goods = baseMapper.selectById(goodsId);
        if(Convert.toInt(goods.getGoodsStock())>0){
            goods.setGoodsStock(goods.getGoodsStock().subtract(new BigDecimal(number)));
            baseMapper.updateById(goods);
        }
    }
}
